package lyttest.uils;

import com.alibaba.fastjson.JSON;
import lyttest.enums.BaseEnum;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * @author jeff.chen
 * @file Response
 * @E-mail chenjf159@chinaunicom.cn
 */
public class Response<T> implements Serializable {

    static final Object EMPTY = null;

    /**
     * 返回信息
     */
    private String msg;

    /**
     * code码
     */
    private Integer code;

    /**
     * 数据
     */
    private T data;

    /**
     * 是否成功
     */
    private Boolean success;

    /**
     * 异常信息描述
     */
    private String exception;

    /**
     * 附件
     */
    private Map<String, String> attachment;

    protected Response() {
    }

    private Response(String msg, Integer code, T data, Boolean success) {
        this.msg = msg;
        this.code = code;
        this.data = data;
        this.success = success;
    }

    public Response(String msg, T data, Boolean success) {
        this.msg = msg;
        this.data = data;
        this.success = success;
    }

    public Response(String msg, Boolean success) {
        this.msg = msg;
        this.success = success;
    }

    public Response(String msg, Integer code, T data, Boolean success, String exception) {
        this.msg = msg;
        this.code = code;
        this.data = data;
        this.success = success;
        this.exception = exception;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public static Response createSuccess(String msg) {
        return createSuccess(msg, null);
    }

    public static Response createSuccess(Object data) {
        return createSuccess(BaseEnum.SUCCESS.getMsg(), data);
    }

    public static Response createSuccess(String msg, Object data) {
        return createSuccess(msg, BaseEnum.SUCCESS.getCode(), data);
    }

    public static Response createSuccess(String msg, Object data, String... args) {
        return createFormatMsg(msg, BaseEnum.SUCCESS.getCode(), data, true, args);
    }

    public static Response createSuccess(String msg, String... args) {
        return createFormatMsg(msg, BaseEnum.SUCCESS.getCode(), null, true, args);
    }

    public static Response createSuccess(String msg, Integer code, Object data) {
        return new Response<>(msg, code, data, true);
    }

    public Boolean isSuccess() {
        return success;
    }

    public Boolean getSuccess() {
        return success;
    }

    public String getException() {
        return exception;
    }

    public void setException(String exception) {
        this.exception = exception;
    }

    public static Response createSuccess() {
        return new Response<>(BaseEnum.SUCCESS.getMsg(), BaseEnum.SUCCESS.getCode(), null, true);
    }

    public static Response createError() {
        return new Response<>(BaseEnum.ERROR.getMsg(), BaseEnum.ERROR.getCode(), EMPTY, false);
    }

    public static Response createError(String msg) {
        return createFormatMsg(msg, BaseEnum.ERROR.getCode(), EMPTY, false);
    }

    public static Response createError(String msg, String... args) {
        return createFormatMsg(msg, BaseEnum.ERROR.getCode(), EMPTY, false, args);
    }

    public static Response createError(String msg, Object data, String... args) {
        return createFormatMsg(msg, BaseEnum.ERROR.getCode(), data, false, args);
    }

    public static Response createError(String msg, Object data) {
        return new Response<>(msg, BaseEnum.ERROR.getCode(), data, false);
    }

    public static Response createError(String msg, Integer code, Object data) {
        return new Response<>(msg, code, data, false);
    }

    public static Response createError(String msg, Integer code) {
        return createFormatMsg(msg, code, EMPTY, false);
    }

    public static Response createError(String msg, String exception) {
        return new Response<>(msg, BaseEnum.ERROR.getCode(), EMPTY, false, exception);
    }

    /**
     * 格式化msg
     *
     * @param msg
     * @param code
     * @param data
     * @param success
     * @param args    格式化参数 eg：%s占位符
     * @return
     */
    private static Response createFormatMsg(String msg, Integer code, Object data, Boolean success, String... args) {
        return new Response<>(String.format(msg, args), code, data, success);
    }

    public Map<String, String> getAttachment() {
        return attachment;
    }

    public void setAttachment(Map<String, String> attachment) {
        if (null == attachment) {
            return;
        }

        this.attachment = attachment;
    }

    public synchronized void setAttachment(String key, String value) {
        if (null == this.attachment) {
            this.attachment = new HashMap<>(8);
        }

        this.attachment.put(key, value);
    }

    @Override
    public String toString() {
        return "Response{" +
                "msg='" + msg + '\'' +
                ", code=" + code +
                ", data=" + JSON.toJSONString(data) +
                ", success=" + success +
                ", exception='" + exception + '\'' +
                ", attachment=" + JSON.toJSONString(attachment) +
                '}';
    }
}
